﻿
using System;

namespace Patterns4Net.PatternEnforcer.Cmd.Output
{
    using System.Collections.Generic;
    using System.Diagnostics.Contracts;
    using System.IO;
    using Mono.Cecil;
    using Core;

    /// <summary>
    /// Provides a strategy to output <see cref="PatternEnforcer"/> result 
    /// in format for normal command line output (human readable, not so detailed).
    /// </summary>
    public class CommandLineOutputFormatter : IOutputFormatter
    {
        public void Start(TextWriter writer)
        {            
        }

        public void Print(IEnumerable<PatternEnforcer.ResultItem> result, TextWriter writer)
        {
            foreach (var resultItem in result)
            {
                string memberName = GetMemberName(resultItem);

                foreach (var checkerResultPair in resultItem.CheckerResults)
                {
                    var pattern = checkerResultPair.Key;
                    var checkerResult = checkerResultPair.Value;
                    writer.WriteLine();
                    writer.WriteLine("-----------");
                    if (checkerResult.IsValid)
                    {
                        writer.WriteLine(
                            "{0}, pattern {1} - OK (checked rules: {2})",
                            memberName,
                            resultItem.GetType().Name,
                            checkerResult.CheckedRulesCount);
                    }
                    else
                    {
                        writer.WriteLine(
                            "{0}, pattern {1} - ERROR, (checked rules: {2}, errors: {3})",
                            memberName,
                            pattern.GetType().Name,
                            checkerResult.CheckedRulesCount,
                            checkerResult.ErrorsCount);
                        foreach (var error in checkerResult.Errors)
                        {
                            writer.WriteLine(error.Message);
                        }
                    }                        
                }
            }
        }

        public void End(TextWriter writer)
        {
        }

        private static string GetMemberName(PatternEnforcer.ResultItem resultItem)
        {
            if (resultItem.Member is MethodDefinition)
            {
                return string.Format(
                    "Type {0}, method {1}",
                    resultItem.Member.DeclaringType.Name,
                    resultItem.Member.Name);
            }

            if (resultItem.Member is TypeDefinition)
            {
                return string.Format(
                    "Type {0}",
                    resultItem.Member.Name);
            }

            Contract.Assert(
                false,
                string.Format("OuputResultCommandLine unexpected member type {0}", resultItem.Member.GetType()));
            return resultItem.Member.ToString();
        }
    }
}
